using System.Data;
using SqlSugar;

namespace DiLu.Expansion.DataStorage.Common.ColumnDataConverts;

/// <summary>
///     提供Ulid（Universally Unique Lexicographically Sortable Identifier）类型的转换功能
///     用于在数据库操作中实现自定义参数化和查询结果的转换。
///     实现了ISugarDataConverter接口，支持SqlSugar框架中的数据转换逻辑。
///     该类主要用于处理Ulid类型的数据在数据库存储和读取过程中的格式转换，确保数据的一致性和正确性。
/// </summary>
public class UlidConvert : ISugarDataConverter
{
    public SugarParameter ParameterConverter<T>(object columnValue, int columnIndex)
    {
        if (typeof(T) != typeof(Ulid))
            throw new ArgumentException(ErrorMessages.ParameterUnsupportedType);

        return new SugarParameter($"@ulid{columnIndex}", $"{columnValue}");
    }

    public T QueryConverter<T>(IDataRecord dataRecord, int dataRecordIndex)
    {
        if (typeof(T) != typeof(Ulid))
            throw new InvalidOperationException(ErrorMessages.QueryUnsupportedType);

        return ConvertToUlid<T>(dataRecord.GetValue(dataRecordIndex), dataRecordIndex);
    }

    /// <summary>
    ///     将指定的值转换为Ulid类型。
    ///     该方法主要用于在查询结果中将数据库字段值转换为Ulid类型，确保数据类型的正确性。
    ///     如果值无法解析为有效的Ulid格式，则抛出FormatException异常。
    /// </summary>
    /// <param name="value">需要转换的对象值，通常是从数据库读取的字段值。</param>
    /// <param name="dataRecordIndex">数据记录中字段的索引位置，用于定位和错误提示。</param>
    /// <typeparam name="T">目标转换类型，必须为Ulid类型。</typeparam>
    /// <returns>转换后的Ulid对象，如果输入值为DBNull，则返回默认值。</returns>
    /// <exception cref="FormatException">当值无法解析为有效的Ulid格式时抛出。</exception>
    private T ConvertToUlid<T>(object value, int dataRecordIndex)
    {
        if (Ulid.TryParse($"{value}", out var ulid))
            return (T)(object)ulid;

        throw new FormatException(string.Format(ErrorMessages.InvalidUlidFormat, dataRecordIndex, value));
    }

    // 常量定义
    private static class ErrorMessages
    {
        public const string ParameterUnsupportedType = "ParameterConverter 仅支持 Ulid 类型。";
        public const string QueryUnsupportedType = "QueryConverter 仅支持 Ulid 类型。";
        public const string InvalidUlidFormat = "索引 {0} 处的字段的 Ulid 格式无效：{1}";
    }
}